package com.components.identifyingcode
{	
	/**
	 * @auth Chunning
	 * @purpose identifying code...
	 * @date 2009-3-22
	 * */	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	import utils.display.MCUtils;

	public class IdentifyingCode extends Sprite
	{
		//START
		
		//PROPERTY
		private var background:Sprite;
		
		private var txtModel:TextField;
		
		private var code:String;
		
		private var _codeNum:uint = 4;
		
		private var arrFun:Array;
		
		private var bmShow:Bitmap;
		
		private var singleWidth:Number;
		
		private var singleHeight:Number;
		
		private var showWidth:Number;
		
		private var showHeight:Number;
		
		private var _different:Boolean;
		
		//CONSTRUCTOR
		public function IdentifyingCode()
		{
			
			init();
									
		}
		
		//METHODS
		
		//init...
		private function init():void
		{
			
			this.background = MCUtils.getInstance(this,"background") as Sprite;
			
			this.txtModel = MCUtils.getInstance(this,"txtModel") as TextField;
			
			this.showWidth = this.txtModel.width;
			
			this.showHeight = this.txtModel.height;
			
			this.singleWidth = showWidth / this._codeNum;
			
			this.singleHeight = showHeight;
			
			this.txtModel.visible = false;
						
			this.bmShow = new Bitmap(new BitmapData(this.txtModel.width,this.txtModel.height,true,0x00000000));
			
			this.bmShow.x = txtModel.x;
			
			this.bmShow.y = txtModel.y;
			
			this.addChild(bmShow);
			
			this.arrFun = [this.createLowerLetter,this.createNum,this.createUpperLetter];
			
			this.mouseEnabled = false;
			
			this.mouseChildren = false;
			
			createCode();
			
		}
		
		//create code...
		private function createCode():void
		{
			this.code = "";
			
			var singleCode:String;
			
			var index:uint;
			
			var matrix:Matrix;
			
			var center:Point;
			
			var newCenter:Point;
					
			this.txtModel.autoSize = TextFieldAutoSize.LEFT;
												
			for(var i:int = 0;i < this._codeNum;i++)
			{
				
				index = Math.floor(Math.random() * this.arrFun.length);
				
				singleCode = this.arrFun[index]()
								
				this.txtModel.text = singleCode;
				
				center = new Point(this.txtModel.width / 2,this.txtModel.height / 2);
								
				matrix = new Matrix;
				
				matrix.rotate( Math.pow(-1,Math.floor(Math.random() * 2)) * Math.random() * (Math.PI / 6) );
								
				matrix.scale(this.singleWidth / this.txtModel.width,this.singleHeight / this.txtModel.height);
				
				newCenter = matrix.transformPoint(center);
								
				matrix.translate((center.x - newCenter.x) + i * this.singleWidth + (this.singleWidth - this.txtModel.width ) / 2 + 2,center.y - newCenter.y);
												
				this.bmShow.bitmapData.draw(this.txtModel,matrix);
				
				this.code += singleCode;	
																		
			}
						
		}
		
		//create upper case letter...
		private function createUpperLetter():String
		{
			
			var unicode:uint;
			
			do
			{
				
				unicode = 65 + Math.floor(Math.random() * 26);
				
			}while(unicode == 79 || unicode == 73);			
			
							
			return String.fromCharCode(unicode);
		}
		
		//create lower case letter..
		private function createLowerLetter():String
		{
			var unicode:uint;
			
			do
			{				
				unicode = 97 + Math.floor(Math.random() * 26);
				
			}while(unicode == 108 || unicode == 111 );			
							
			return String.fromCharCode(unicode);
			
		}
		
		
		//create num...
		private function createNum():String
		{
			
			var unicode:uint = 50 + Math.floor(Math.random() * 8);
							
			return String.fromCharCode(unicode);
			
		}
		
		//check..
		public function check(code:String):Boolean
		{
			
			var correct:Boolean;
			
			if(this._different)
			{
				
				correct = code == this.code;
				
			}else{
				
				
				correct = code.toLowerCase() == this.code.toLowerCase();
				
			}
			
			return correct;
			
		}
		
		
		//refresh..
		public function refresh():void
		{
									
			this.singleWidth = showWidth / this._codeNum;
			
			this.singleHeight = showHeight;
			
			this.bmShow.bitmapData = new BitmapData(showWidth,showHeight,true,0x00000000);
			
			this.createCode();	
									
		}
		
		//set code num...
		public function set codeNum(val:uint):void
		{
			
			this._codeNum = val;
			
			this.refresh();
			
			
		}
		
		//differentiate upper case or lower case...
		public function set diffUperOrLower(val:Boolean):void
		{
			
			this._different = val;
			
		}
		
		public function get diffUperOrLower():Boolean
		{
			
			return this._different;
			
		}
		
				
		//END
	}
}